Completed
Push — dev ( 3403e5...41defb )
by Fike
30s
created

Normalizer.state   A

Complexity

Conditions 4
Paths 16

Size

Total Lines 18

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 4
nc 16
dl 0
loc 18
rs 9.2
c 1
b 0
f 0
nop 3

1 Function

Rating   Name   Duplication   Size   Complexity  
A 0 1 1
1
var Objects = require('../Utility').Objects
2
var Defaults = require('./Defaults')
3
4
var Normalizer = {
5
  /**
6
   * @param {TStateTrigger|string} trigger
7
   * @return {TStateTrigger}
8
   */
9
  stateTrigger: function (trigger) {
10
    if (typeof trigger === 'string') {
11
      trigger = {id: trigger}
12
    }
13
    if (!Objects.isObject(trigger) || !trigger.id) {
14
      return null
15
    }
16
    var hints = trigger.hints
17
    if (!Objects.isObject(hints) && !Objects.isFunction(hints)) {
18
      trigger.hints = {}
19
    }
20
    return trigger
21
  },
22
  /**
23
   * Normalizes transition output.
24
   *
25
   * @param {TTransitionReturn|string} result
26
   * @return {TTransitionReturn}
27
   */
28
  transition: function (result) {
29
    result = Objects.copy(result, true)
30
    if (typeof result === 'string') {
31
      result = {trigger: result}
32
    } else if (!Objects.isObject(result)) {
33
      result = {}
34
    }
35
    result.trigger = Normalizer.stateTrigger(result.trigger)
36
    if (typeof result.transitionedTo !== 'string') {
37
      result.transitionedTo = null
38
    }
39
    return result
40
  },
41
  /**
42
   * @param {TState|Function} state
43
   * @param {TStateId} id
44
   * @param {object<string, (int|null)>} timeouts
45
   * @return {TState}
46
   */
47
  state: function (state, id, timeouts) {
48
    if (Objects.isFunction(state)) {
49
      state = {transition: state}
50
    }
51
    state = Objects.copy(state, true)
52
    state.id = typeof state.id === 'string' ? state.id : id
53
    state.entrypoint = !!state.entrypoint
54
    state.terminal = !!state.terminal
55
    var handler = state.transition || function () {}
56
    state.transition = Normalizer.handler(handler, 'transition', timeouts)
57
    handler = state.abort || function () {}
58
    state.abort = Normalizer.handler(handler, 'abort', timeouts)
59
    state.triggers = Normalizer.stateTrigger(state.triggers)
60
    if (!state.hasOwnProperty('timeout')) {
61
      state.timeout = timeouts.state
62
    }
63
    return state
64
  },
65
  /**
66
   * @param {TStateHandler|Function} handler
67
   * @param {string} id
68
   * @param {object<string, (int|null)>} timeouts
69
   *
70
   * @return {TStateHandler}
71
   */
72
  handler: function (handler, id, timeouts) {
73
    var cursor = handler && handler.handler
74
    var defaultHandler = function () { return cursor }
75
    handler = Normalizer.singleHandler(handler, defaultHandler, id, timeouts)
76
    if (handler.onTimeout) {
77
      var name = 'on' + id[0].toUpperCase() + id.substr(1) + 'Timeout'
78
      handler.onTimeout = Normalizer.handler(handler.onTimeout, name, timeouts)
79
    }
80
    return handler
81
  },
82
  /**
83
   * @param {TStateHandler|Function} handler
84
   * @param {Function} defaultHandler
85
   * @param {string} id
86
   * @param {object<string, (int|null)>} timeouts
87
   *
88
   * @return {TStateHandler}
89
   */
90
  singleHandler: function (handler, defaultHandler, id, timeouts) {
91
    if (Objects.isFunction(handler)) {
92
      handler = {handler: handler}
93
    }
94
    if (!Objects.isObject(handler)) {
95
      handler = {}
96
    }
97
    handler.id = id
98
    if (!Objects.isFunction(handler.handler)) {
99
      handler.handler = defaultHandler
100
    }
101
    if (!handler.hasOwnProperty('timeout')) {
102
      handler.timeout = timeouts[id]
103
    }
104
    return handler
105
  },
106
  /**
107
   * @param {TScenarioInput} input
108
   *
109
   * @return {TScenario}
110
   */
111
  scenario: function (input) {
112
    if (!Objects.isObject(input)) {
113
      throw new Error('Provided scenario is not an object')
114
    }
115
    var scenario = Objects.copy(input, true)
116
    var timeouts = Objects.copy(Defaults.Timeouts)
117
    timeouts = Objects.merge(timeouts, input.timeouts || {})
118
    var handlers = ['onError', 'onTermination']
119
    handlers.forEach(function (name) {
120
      scenario[name] = Normalizer.handler(scenario[name], name, timeouts)
121
    })
122
    scenario.states = scenario.states || {}
123
    Object.keys(scenario.states).forEach(function (key) {
124
      scenario.states[key] = Normalizer.state(scenario.states[key], key, timeouts)
125
    })
126
    scenario.timeout = timeouts.scenario
127
    scenario.deserializer = Normalizer.deserializer(scenario.deserializer, timeouts)
128
    return scenario
129
  },
130
  /**
131
   * @param {THandler|Function|*} handler
132
   * @param {object.<string, (int|null)>} timeouts
133
   *
134
   * @return {TStateHandler}
135
   */
136
  deserializer: function (handler, timeouts) {
137
    if (!Objects.isObject(handler)) {
138
      handler = {handler: handler}
139
    }
140
    if (!Objects.isFunction(handler.handler)) {
141
      handler.handler = Defaults.Deserializer
142
    }
143
    return Normalizer.handler(handler, 'deserializer', timeouts)
144
  }
145
}
146
147
module.exports = {
148
  Normalizer: Normalizer
149
}
150